#include <sys/syscall.h>
#include <mips/regdef.h>
#include "base64.h"
#include "encode64.h"
	.section .mdebug.abi32
	.previous
	.abicalls
	.text
	.align	2
	.globl	mygetc
	.ent	mygetc
mygetc:
	.frame $fp,48,ra # 16 ABA + 16 LTA + 16 SRA
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,48
	.cprestore 16			# posicion de gp
	sw  $ra,40($fp)
	sw	$fp,36($sp)
	sw	$gp,32($sp)
	move	$fp,$sp
	sw	$a0,48($fp)
	li	$v0,SYS_read
	li	$a0,48($fp)
	la	$a1,16($fp)
	li	$a2,1
	syscall
	bne $a3,$zero,read_error #chequeo read error
	bez $v0,EOF #leyo 0, eof
	li	$t0,1
	bne	$v0,$t0,read_error #cantidad leida
	b FIN_MYGETC
read_error:
	li v0,SYS_exit
	li a0,1
	syscall
EOF:
	sw  $zero,16($fp)#retorna 0
FIN_MYGETC:
	lw  $v0,16($fp)
	lw	$ra,40($sp)
	lw	$fp,36($sp)
	lw	$gp,32($sp)
	addiu $sp,$sp,48
	j 	$ra
	.end
	.end mygetc
	.size mygetc .-mygetc
	.align	2
	.globl	myputc
	.ent	myputc
myputc:
	.frame $fp,48,ra # 16 ABA + 16 LTA + 16 SRA
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,48
	.cprestore 32			# posicion de gp
	sw  $ra,40($fp)
	sw	$fp,36($sp)
	sw	$gp,32($sp)
	move	$fp,$sp
	sw	$a0,48($fp)
	sw	$a1,52($fp)
	li	$v0,SYS_write
	li	$a0,52($fp) #puntero a archivo
	la	$a1,48($fp) #caracter a escribir
	li	$a2,1
	syscall
	bne $a3,$zero,write_error #chequeo write error
	li	$t0,1
	bne	$v0,$t0,write_error #cantidad leida
	b FIN_MYPUTC
write_error:
	li v0,SYS_exit
	li a0,1
	syscall
FIN_MYPUTC:
	lw	$ra,40($sp)
	lw	$fp,36($sp)
	lw	$gp,32($sp)
	addiu $sp,$sp,48
	j 	$ra
	.end
	.end myputc
	.size myputc .-myputc
	.align	2
	.globl	base64_encode
	.ent	base64_encode
base64_encode:
	.frame $fp,80,ra # 16 ABA + 48 LTA + 16 SRA
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,80
	.cprestore 64			# posicion de gp
	sw  $ra,72($fp)
	sw	$fp,68($sp)
	sw	$gp,64($sp)
	move	$fp,$sp
	sw	$a0,80($fp)
	sw	$a1,84($fp)
	sw	$zero,16($fp)		#count=0
	sw	$zero,20($fp) 		#b[0]=0
	sw	$zero,24($fp)  		#b[1]=0
	sw	$zero,28($fp)  		#b[2]=0
	sw	$zero,32($fp)		#be[0]=be[1]=be[2]=be[3]=0

	sw	$zero,36($fp)		#rc=0
	sw	$zero,40($fp)		#i=0
WHILE_ENCODE:
	lw	$v0,36($fp)			# load rc
	li	$v0,-1			# EOF=-1
	sw  $zero,40($fp)
	bne	$v0,$v1,FOR_1		# rc!=EOF
	b	FIN_BASE64_E
FOR_1:
	lw	$v0,40($fp)			#v0=i
	li	$v1,3
	bge $v0,$v1,FIN_FOR_1	# si 3>=i salir
#Llamo a migetc
	lw	$v0,80($fp)			#cargo infd
	move $a0,$v0
	la  $t9,mygetc			#direccion de mygetc
	jal $ra,$t9				#pido el caracter
	sw  $v0,36($fp)			#guardo rc
	li	$v1,-1				#cargo EOF
	be  $v0,$v1,FIN_FOR_1
#buffer[i++]=rc
	lw   $v0,40($fp)		#cargo i
	sll  $v0,$v0,2			#multiplico por 4
	addu $v1,$fp,20			#direccion de b[0]
	addu $v0,$v0,$v1		#direcciono el b[i]
	lw	 $v1,36($fp)		#leo rc
	sw	 $v1,0($v0)			#buffer[i]=rc
	lw	 $v0,40($fp)
	addiu $v0,$v0,1 		#i++
	lw	 $v0,40($fp)
	b	FOR_1
FIN_FOR_1:
	lw	 $v0,40($fp)		#i
	blez $v0,FIN_IF_1
IF_1:
	addu $a0,$fp,20
	addu $a1,$fp,32
	lw  $v0,40($fp)
	la	$t9,doEncode
	jal	$ra,$t9
	sw  $v0,$44($fp)		#guardo el retorno de doEncode
#if (a!=0) retorno el error
	bnez $v0,FIN_ERROR_BASE64_E
#levanto count para ver si debo agregar fin de linea
	lw	$v0,16($fp)
	li  $v1,76
	blt $v0,$v1,WRITE_ENCODE
	li	$v0,10  #salto de linea es ascii 10
	move $a0,$v0
	lw	$v0,84($fp) #outfd
	move $a1,$v0
	la	$t9,myputc
	jal	$ra,$t9
	sw	$zero,16($fp)

WRITE_ENCODE:
#fwrite(bufferEncoded,1,4,fpout)
#COMPLETAR LA ESCRITURA
	lb	$v0,32($fp)  #salto de linea es ascii 10
	move $a0,$v0
	lw	$v0,84($fp) #outfd
	move $a1,$v0
	la	$t9,myputc
#seg byte encodeado	
	lb	$v0,33($fp)  #salto de linea es ascii 10
	move $a0,$v0
	lw	$v0,84($fp) #outfd
	move $a1,$v0
	la	$t9,myputc
#tercer byte encodeado
	lb	$v0,34($fp)  #salto de linea es ascii 10
	move $a0,$v0
	lw	$v0,84($fp) #outfd
	move $a1,$v0
	la	$t9,myputc
#cuarto byte
	lb	$v0,35($fp)  #salto de linea es ascii 10
	move $a0,$v0
	lw	$v0,84($fp) #outfd
	move $a1,$v0
	la	$t9,myputc

#aumento count en 4
	lw $v0,16($fp)
	addiu $v0,$v0,4
	sw	$v0,16($fp)
	b WHILE_ENCODE

FIN_ERROR_BASE64_E:
	lw	$v0,44($fp)
	b   FIN_BASE64_E_2
FIN_IF_1:
FIN_BASE64_E:
	move $v0,$zero
FIN_BASE64_E_2
	lw 	 $ra,72($sp)
	lw	 $fp,68($sp)
	lw   $gp,64($sp)
	addu $sp,$sp,80
	.end base_64encode
	.size base_64encode .-base_64encode
